package com.bxji.spring.ms.geteway;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

/**
 * 自定义过滤器：token校验/安全认证 <br/>
 * 安全校验，一般放在请求真正处理之前，所以filterType指定为pre
 * 
 * @author bxji
 */
//@Component
public class AccessFilter extends ZuulFilter {

    private static Logger logger = LoggerFactory.getLogger(AccessFilter.class);

    /*
     * zuul过滤器有四种类型分别是：pre 路由前,route 路由时,post 路由完毕,error 发生错误时。
     * 
     * @see com.netflix.zuul.ZuulFilter#filterType()
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /*
     * filter执行顺序，通过数字指定 ,优先级为0，数字越大，优先级越低
     * 
     * @see com.netflix.zuul.ZuulFilter#filterOrder()
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /*
     * 是否执行该过滤器，此处为true，说明需要过滤
     * 
     * @see com.netflix.zuul.IZuulFilter#shouldFilter()
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        String token = request.getParameter("token");

        // 校验token
        if (StringUtils.isNotBlank(token) && token.equals("miniooc")) {
            // TODO 根据token获取相应的登录信息，进行校验 
            ctx.setSendZuulResponse(true); // 对请求进行路由
            ctx.setResponseStatusCode(200);
            ctx.set("code", 1);
        } else {
            logger.info("token为空，禁止访问!");
            ctx.setSendZuulResponse(false); // 不对其进行路由
            ctx.setResponseStatusCode(401);
            HttpServletResponse response = ctx.getResponse();
            response.setHeader("content-type", "text/html;charset=utf8");
            ctx.setResponseBody("网关认证失败，停止路由");
            ctx.set("code", 0);
            return null;
        }

        // 添加 Basic Auth 认证信息
        ctx.addZuulRequestHeader("Authorization", "Basic " + getBase64Credentials("app01", "*****"));

        return null;
    }

    private String getBase64Credentials(String username, String password) {
        String plainCreds = username + ":" + password;
        byte[] plainCredsBytes = plainCreds.getBytes();
        byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
        return new String(base64CredsBytes);
    }
}